Floating Point
因為形式一定是1.~,我們偷了最前面1這個bit,卻無法表達0了
解決Floating Point無法表達0
大家可以看到 signed bit的部分可能是0或是1
但是exponent必須全為0 fraction也全為0
所以我們會有正的0 同時也會有負的0
為什麼我們會需要正的0跟負的0不是應該只有一個嗎
實際上在浮點數的設計裡面 這樣的設計反而是比較好的
因為在有些情況之下 我們很可能我們要表達的數字其實非常非常的小 非常的接近於0
這個時候我們會希望知道的事情是 到底這個非常接近於0的數字
它到底是大於0 還是小於0
如果它是稍微大於0的 我們就用正的0來表示它
反過來說 如果它原本就是一個小於0的情況 我們就用負的0去表示它
優點:
我們可以針對一些非常小 非常非常小的數字
也就是一個非常極限的情況的時候 依然能夠去做比大小的動作
underflow
最小可以表達的一個合法的一個數字是這麼小的話 那麼如果我們想要表達的數字
是比這個最小可以表達的數字更小的
overflow
而如果我們想要表達的數字 是比我們可以表達的數字還來的大
Gradual(逐漸) Underflow
在IEEE 754的設計裡面 他們設計了一個非常有趣的一個representation叫做Gradual Underflow
Gradual Underflow的意思就是逐漸的朝向underflow的方向走
設計的概念就是希望如果我們已經沒有辦法 用剛才前面我們所介紹的最接近於0的這樣子的一個表示法
去表達一個浮點數的時候 我們採取了一個很特別的設計
這個設計叫做"denormalized number"
denormalized 意思就是指它其實已經不是一個標準的數字了
標準的浮點數就是之前我們所定義的浮點數的表示法
大家應該有印象 在fraction或者是significand的前面
也就是小數點前面 我們有一個hidden的leading 1
前面有一個1做為開頭 而在denormalized的number裡面 我們讓這個1不見
也就是說我們讓小數點的開頭變成是0 而後面接上significand
透過這樣子的設計 因為少了這個leading的1 實際上我們就可以表達出更小的數字了
解釋:
為了要讓fraction不為0的情況 也可以拿來表達一些浮點數的特殊情況的話
我們採取的做法就是讓fraction當它不等於0的時候 而exponent等於0的時候
我們讓前面的這個leading變成0
既然是0開頭的 實際上後面這一串它是不等於0的
可是它能夠表達的數字就會比前面我們剛才所談到最小的 合法的浮點數它表達的數字範圍的最小值來的更小
例子
一個最小的normalized number 也就是合法的number
就會是前面有一個leading 1 而fraction全為0
而實際上exponent它的值是1 1減掉biased 127之後會得到-126
有了gradual underflow這樣一個設計
當exponent為0的時候 這時其實leading 1不見了
我們讓它一定都是0開頭
如果fraction這個數字它不等於0的話 實際上這個數字它非常的接近0但不等於0
而最小能夠表達的數字就是fraction每個bit都為0
除了最低位元以外 最低位元為1
正負無窮大
在IEEE 754的設計裡面 如果我們想要表達的數字範圍已經超過了我們最大可以表達的數字時
時我們就把它定義為無窮大 而無窮大infinity分為正無窮大以及負無窮大
實際上如果我們想要表達一個無窮大的數字時 這時它的exponent就是全為1
在single precision的情況 它就是255 而它的fraction的部分也就是significand必須要全為0
當數字的exponent全為1 而fraction全為0這時代表的就是無窮大
再用它的signed bit來決定它是正無窮大或是負無窮大
gradual overflow? (IEEE 754沒做這東西)
實際上如果我們真的想要拿來設計gradual overflow 9讓它一步一步的往無窮大的方向走 這樣子的概念當然是可以的 但是這樣子的設計對我們來說 能夠得到的好處其實並不多
not a number
不是一個合法的浮點數數字
如果我今天要去做一個開根號-4 或是我們要做一個0除以0
這個我們都知道做完的結果 開根號-4會得到一個虛數
也就是它絕對不會是一個合法的浮點數
除以0這件事情也是非法的
既然如此 我們希望能夠有一個好的方式去表達這種非法也就是它不是數字的這種浮點數
表示:
NaN實際上要表示的時候很簡單 我們只要讓exponent為最大值全為1
在single precision的時候就是255
而我們故意的讓fraction讓它不為0
contaminate 汙染
任何的運算 只要當它在運算的時候發現其中有一個數字是NaN
那麼它就會自動的污染這個運算的結果 也就是說它運算完的結果仍然是NaN
這件事情我們把它叫做contaminate
優點:
有了這樣的汙染 它可以比較方便的幫助我們的程式設計師拿來debug
總結
浮點數相加(十進位為例)
維持指數一樣>相加
讓大家的指數維持一樣的目的
是因為只要讓大家的指數是一樣的同時 我們就可以輕易的針對fraction的部分拿來作加法
步驟:
1.讓這兩個數字它的exponent維持是一致的
2.把它的fraction拿來相加了
3.做一些normalization(希望它用類似科學記號表示法這個概念去表示)
也就是說在小數點前面一定就是一個1 去把小數點向左或向右移動
使得最後得到的數字它的小數點前面就是一個1
4.Check結果是否overflow 或是underflow
Rounding
5.最後如果我們得到的有效位數其實超過23位
因為實際上在single precision裡面 我們最後只有23個bit可以拿來當fraction
所以我們可能會需要做一點點的四捨五入 而這個概念就叫做Rounding
浮點數相加(十進位為例)
步驟:
把fraction的部分拿來做乘法
exponent的部分 我們則需要拿來做加減法
最後有一個特別重要的事情要提醒各位同學
浮點數它的exponent 我們採用的方式是biased notation
single precision會有biased 127
也因此實際上當我們在處理exponent的數字時要非常的小心
所以記得算完最後要扣掉bias的那個量一次